package com.qunar.im.ui.view.EditPictureView;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffXfermode;
import android.graphics.drawable.BitmapDrawable;
import android.util.AttributeSet;
import android.view.GestureDetector;
import android.view.MotionEvent;
import android.view.View;

public class DrawingBoardView extends View {

    /**
     * 画板背景
     **/
    private Bitmap backgroundBitmap = null;

    /**
     * 绘画图层
     **/
    private Bitmap paintBitmap = null;

    /**
     * 绘画板
     **/
    private Canvas paintCanvas = null;

    /**
     * 手势监听
     **/
    private GestureDetector brushGestureDetector = null;
    private BrushGestureListener brushGestureListener = null;

    /**
     * 绘画类型
     **/
    private DrawAttribute.DrawStatus mDrawStatus;

    private int mBrushColor;
    private Paint mPaint;
    private boolean mEditable = false;
    /**
     * 上下文
     **/
    private Context context;

    public DrawingBoardView(Context context, AttributeSet attributeSet) {
        super(context, attributeSet);
        this.context = context;
        brushGestureListener = new BrushGestureListener();
        brushGestureDetector = new GestureDetector(context,
                brushGestureListener);
        mPaint = new Paint();
        mPaint.setAntiAlias(true);
        mPaint.setFilterBitmap(true);
        mPaint.setDither(true);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        canvas.drawColor(Color.WHITE);
        canvas.drawBitmap(backgroundBitmap, 0, 0, mPaint);
        canvas.drawBitmap(paintBitmap, 0, 0, mPaint);
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        brushGestureDetector.onTouchEvent(event);
        postInvalidate();
        return true;
    }

    /**
     * 设置绘制的背景图片 创建绘画画板Canvas
     *
     * @param bitmap 背景图片
     */
    public void setBackgroundBitmap(Bitmap bitmap) {

        backgroundBitmap = bitmap;
        paintBitmap = Bitmap.createBitmap(backgroundBitmap.getWidth(),
                backgroundBitmap.getHeight(), Bitmap.Config.ARGB_8888);
        paintCanvas = new Canvas(paintBitmap);

    }


    /**
     * 设置绘画类型
     *
     * @param drawStatus 绘画类型
     */
    public void setDrawStatus(DrawAttribute.DrawStatus drawStatus) {
        this.mDrawStatus = drawStatus;
    }

    /**
     * 设置画笔颜色
     *
     * @param color 画笔颜色
     */
    public void setPaintColor(int color) {
        this.mBrushColor = color;
    }

    public void setEditable(boolean editable){
        mEditable = editable;
    }

    /**
     * 设置画笔
     *
     * @param drawStatus  绘画类型
     * @param brushBitmap 画笔
     * @param brushColor  画笔颜色
     */
    public void setBrushBitmap(DrawAttribute.DrawStatus drawStatus,
                               Bitmap brushBitmap, int brushColor) {
        this.mDrawStatus = drawStatus;
        this.mBrushColor = brushColor;

        Bitmap tempBrush = null;
        int brushDistance = 0;
        Paint brushPaint1 = null;

        switch (mDrawStatus) {
            case PEN_WATER:

                brushDistance = 1;
                tempBrush = casualStroke(brushBitmap, brushColor);
                brushPaint1 = null;

                break;

            case PEN_CRAYON:

                brushDistance = brushBitmap.getWidth() / 2;
                tempBrush = casualStroke(brushBitmap, brushColor);
                brushPaint1 = null;

                break;

            case PEN_COLOR_BIG:
                tempBrush = casualStroke(brushBitmap, brushColor);
                brushDistance = 2;
                brushPaint1 = null;

                break;

            case PEN_ERASER:
                brushPaint1 = new Paint();
                brushPaint1.setFilterBitmap(true);
                brushPaint1.setXfermode(new PorterDuffXfermode(
                        PorterDuff.Mode.DST_OUT));

                tempBrush = brushBitmap;
                brushDistance = brushBitmap.getWidth() / 4;

                break;

            default:
                break;
        }

        brushGestureListener.setBrush(tempBrush, brushDistance, brushPaint1);
    }

    /**
     * 设置邮票数据
     *
     * @param drawStatus 绘画类型
     * @param res        资源ID数组(大小为4)
     * @param color      颜色
     */
    public void setStampBitmaps(DrawAttribute.DrawStatus drawStatus, int[] res,
                                int color) {
        Bitmap[] brushBitmaps = new Bitmap[4];
        brushBitmaps[0] = casualStroke(res[0], color);
        brushBitmaps[1] = casualStroke(res[1], color);
        brushBitmaps[2] = casualStroke(res[2], color);
        brushBitmaps[3] = casualStroke(res[3], color);

        brushGestureListener.setStampBrush(brushBitmaps);
        this.mDrawStatus = drawStatus;

    }

    class BrushGestureListener extends GestureDetector.SimpleOnGestureListener {

        private Bitmap brushBitmap = null;
        private int brushDistance;

        /**
         * 半个画刷宽度
         **/
        private int halfBrushBitmapWidth;

        /**
         * 画刷
         **/
        private Paint brushPaintListener = null;

        /**
         * 邮票
         **/
        private Bitmap[] stampBrushBitmaps = null;

        /**
         * 是否是邮票
         **/
        private boolean isStamp = false;

        public BrushGestureListener() {
            super();
            isStamp = false;
        }

        @Override
        public boolean onDown(MotionEvent e) {
            if(!mEditable){
                return true;
            }
            getParent().requestDisallowInterceptTouchEvent(true);
            switch (mDrawStatus) {
                case PEN_WATER:
                case PEN_CRAYON:
                case PEN_COLOR_BIG:
                case PEN_ERASER: {
                    isStamp = false;
                    break;
                }
                case PEN_STAMP: {
                    isStamp = true;
                    break;
                }
                default:
                    isStamp = false;
                    break;
            }

            if (isStamp) {
                paintSingleStamp(e.getX(), e.getY());
            } else {
                paintCanvas.drawBitmap(brushBitmap, e.getX()
                                - halfBrushBitmapWidth,
                        e.getY() - halfBrushBitmapWidth, brushPaintListener);
            }

            return true;
        }

        @Override
        public boolean onScroll(MotionEvent e1, MotionEvent e2,
                                float distanceX, float distanceY) {
            if(!mEditable){
                return true;
            }
            getParent().requestDisallowInterceptTouchEvent(true);
            if (isStamp) {
                //paintSingleStamp(e2.getX(), e2.getY());
            } else {
                float beginX = e2.getX();
                float beginY = e2.getY();
                float distance = (float) Math.sqrt(distanceX * distanceX
                        + distanceY * distanceY);
                float x = distanceX / distance, x_ = 0;
                float y = distanceY / distance, y_ = 0;
                while (Math.abs(x_) <= Math.abs(distanceX)
                        && Math.abs(y_) <= Math.abs(distanceY)) {
                    x_ += x * brushDistance;
                    y_ += y * brushDistance;
                    paintCanvas.save();
                    paintCanvas.rotate((float) (Math.random() * 10000), beginX
                            + x_, beginY + y_);
                    paintCanvas.drawBitmap(brushBitmap, beginX + x_
                            - halfBrushBitmapWidth, beginY + y_
                            - halfBrushBitmapWidth, mPaint);
                    paintCanvas.restore();
                }
            }

            return true;
        }

        public void setBrush(Bitmap brushBitmap, int brushDistance,
                             Paint brushPaint) {
            this.brushBitmap = brushBitmap;
            this.brushDistance = brushDistance;
            this.halfBrushBitmapWidth = brushBitmap.getWidth() / 2;
            this.brushPaintListener = brushPaint;
        }

        public void setStampBrush(Bitmap[] brushBitmaps) {
            this.stampBrushBitmaps = brushBitmaps;
            halfBrushBitmapWidth = brushBitmaps[0].getWidth() / 2;
        }

        private void paintSingleStamp(float x, float y) {

            if (Math.random() > 0.1) {
                paintCanvas.drawBitmap(stampBrushBitmaps[0], x
                        - halfBrushBitmapWidth, y - halfBrushBitmapWidth, null);
            }

            for (int i = 1; i < stampBrushBitmaps.length; i++) {
                if (Math.random() > 0.3) {
                    paintCanvas.drawBitmap(stampBrushBitmaps[i], x
                                    - halfBrushBitmapWidth, y - halfBrushBitmapWidth,
                            null);
                }
            }

        }

    }


    /**
     * 将图片涂色
     *
     * @param paintBit 画笔
     * @param color    画笔颜色
     * @return 将画笔(图片)涂色
     */
    private Bitmap casualStroke(Bitmap paintBit, int color) {
        Bitmap bitmap = paintBit.copy(Bitmap.Config.ARGB_8888, true);
        Canvas canvas = new Canvas();
        canvas.setBitmap(bitmap);
        Paint paintUnder = new Paint();
        paintUnder.setColor(color);
        canvas.drawPaint(paintUnder);
        Paint paint = new Paint();
        paint.setFilterBitmap(true);
        paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_OUT));
        canvas.drawBitmap(paintBit, 0, 0, paint);
        paintBit.recycle();
        return bitmap;
    }

    /**
     * 将图片涂色
     *
     * @param drawableId 图片
     * @param color      颜色
     * @return
     */
    private Bitmap casualStroke(int drawableId, int color) {
        Bitmap mode = ((BitmapDrawable) this.getResources().getDrawable(
                drawableId)).getBitmap();
        Bitmap bitmap = mode.copy(Bitmap.Config.ARGB_8888, true);
        Canvas canvas = new Canvas();
        canvas.setBitmap(bitmap);
        Paint paintUnder = new Paint();
        paintUnder.setColor(color);
        canvas.drawPaint(paintUnder);
        Paint paint = new Paint();
        paint.setFilterBitmap(true);
        paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_OUT));
        canvas.drawBitmap(mode, 0, 0, paint);
        return bitmap;
    }

    /**
     * 得到绘画图片
     *
     * @return
     */
    public Bitmap getDrawBitmap() {
        if(backgroundBitmap == null) return null;
        Bitmap bitmap = Bitmap.createBitmap(backgroundBitmap.getWidth(),
                backgroundBitmap.getHeight(), Bitmap.Config.ARGB_8888);
        Canvas canvas = new Canvas(bitmap);
        canvas.drawBitmap(backgroundBitmap, 0, 0, mPaint);
        canvas.drawBitmap(paintBitmap, 0, 0, mPaint);
        canvas.save();
        return bitmap;
    }
}